<template>
    <el-form :model="form" class="container">
        <el-form-item>
            <el-input v-model="form.subject" placeholder="请输入科目" size="default" style="width: 100%" />
        </el-form-item>
        <component :is="renderFormItem('单选题', 'singleChoiceNum', 'singleChoiceScore')" />
        <component :is="renderFormItem('多选题', 'multipleChoiceNum', 'multipleChoiceScore')" />
        <component :is="renderFormItem('判断题', 'judgementNum', 'judgementScore')" />
        <component :is="renderFormItem('填空题', 'fillInTheBlankNum', 'fillInTheBlankScore')" />
        <component :is="renderFormItem('问答题', 'questionAnswerNum', 'questionAnswerScore')" />
        <el-collapse accordion v-if="showThinking" v-model="activeNames">
            <el-collapse-item name="thinking">
                <template #title="{ isActive }">
                    <div :class="['title-wrapper', { 'is-active': isActive }]">
                        <el-icon v-if="isThinking" class="rotating"><Loading /></el-icon>
                        <span>{{ isThinking ? `思考中${process}` : "已完成" }}</span>
                    </div>
                </template>
                <div>{{ response }}</div>
            </el-collapse-item>
        </el-collapse>
    </el-form>
</template>

<script setup lang="ts">
import { ref, reactive, h, onUnmounted } from "vue";
import { ElFormItem, ElCol, ElInputNumber } from "element-plus";
import { SSE } from "@/utils/sse";

//生成试卷弹窗->显示思考过程
const showThinking = ref<boolean>(false);

//是否正在思考
const isThinking = ref<boolean>(true);

const activeNames = ref<string[]>(["thinking"]);

//思考进度
const process = ref<string>("");
const processTimer = ref<number>();
const initProcess = () => {
    processTimer.value = window.setTimeout(() => {
        process.value += ".";
        if (process.value.length > 3) {
            process.value = "";
        }
        initProcess();
    }, 500);
};

//生成试卷时的响应信息
const response = ref<string>("");

//生成试卷弹窗->取消
const onCancel = () => {
    processTimer.value && clearTimeout(processTimer.value);
    generatePaperInstance.value && generatePaperInstance.value.disconnect();
    activeNames.value = [];
    isThinking.value = true;
    showThinking.value = false;
    //清空数据
    Object.keys(form).forEach((item: any) => (form[item] = null));
};

//生成试卷form
const form = reactive<any>({
    singleChoiceNum: null,
    singleChoiceScore: null,
    multipleChoiceNum: null,
    multipleChoiceScore: null,
    judgementNum: null,
    judgementScore: null,
    fillInTheBlankNum: null,
    fillInTheBlankScore: null,
    questionAnswerNum: null,
    questionAnswerScore: null,
    subject: null,
});

//生成试卷实例
const generatePaperInstance = ref<SSE | null>(null);

//生成试卷弹窗->确定
const onSubmit = () => {
    console.log(form);
    initProcess();
    showThinking.value = true;
    generatePaperInstance.value = new SSE(`paper/generatePaper`, {
        body: form,
        method: "POST",
        onMessage: (data: any) => {
            response.value += data;
        },
        onError: (error: Error) => {
            response.value += "生成试卷出现错误：" + error.message;
            generatePaperInstance.value && generatePaperInstance.value.disconnect();
            showThinking.value = false;
        },
    });
};

//使用defineEmits注册一个自定义事件
const emit = defineEmits(["onGenerateOver"]);

//渲染表单项
const renderFormItem = (type: string, num: string, score: string) => {
    return h(
        ElFormItem,
        {},
        {
            default: () => [
                h(
                    ElCol,
                    { span: 12 },
                    {
                        default: () =>
                            h(
                                ElInputNumber,
                                {
                                    modelValue: form[num],
                                    "onUpdate:modelValue": (value) => (form[num] = value),
                                    min: 0,
                                    max: 10,
                                    step: 1,
                                    precision: 0,
                                    size: "default",
                                    controlsPosition: "right",
                                    style: { width: "100%" },
                                },
                                {
                                    prefix: () => type + "共",
                                    suffix: () => "道",
                                }
                            ),
                    }
                ),
                h(
                    ElCol,
                    { span: 12 },
                    {
                        default: () =>
                            h(
                                ElInputNumber,
                                {
                                    modelValue: form[score],
                                    "onUpdate:modelValue": (value) => (form[score] = value),
                                    min: 1,
                                    max: 30,
                                    step: 1,
                                    precision: 0,
                                    size: "default",
                                    controlsPosition: "right",
                                    style: { width: "100%" },
                                },
                                {
                                    prefix: () => "每道题",
                                    suffix: () => "分",
                                }
                            ),
                    }
                ),
            ],
        }
    );
};

onUnmounted(() => {
    processTimer.value && clearTimeout(processTimer.value);
    generatePaperInstance.value && generatePaperInstance.value.disconnect();
});

//把方法暴露给父组件使用
defineExpose({
    onSubmit,
    onCancel,
});
</script>

<style scoped lang="less">
.container {
    height: calc(100vh - 350px);
    overflow-y: auto;
    overflow-x: hidden;

    .rotating {
        animation: rotate 1.5s linear infinite;
    }

    @keyframes rotate {
        from {
            transform: rotate(0deg);
        }
        to {
            transform: rotate(360deg);
        }
    }

    .title-wrapper {
        display: flex;
        align-items: center;
        font-size: 15px;
        font-weight: bold;
        color: #232222;
        gap: 8px;
    }
}
</style>
